package com.salts.service.Impl;

import com.salts.Dao.*;
import com.salts.domain.dto.ClothDto;
import com.salts.domain.dto.OrderDeliverDto;
import com.salts.domain.dto.Result;
import com.salts.domain.po.*;
import com.salts.domain.vo.CarVo;
import com.salts.domain.vo.DisplayClothVo;
import com.salts.enums.Freight;
import com.salts.enums.ShoppingCarStaticNum;
import com.salts.service.ShoppingCarService;
import com.salts.util.GetNowDateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ShoppingCarServiceImpl implements ShoppingCarService {
    @Autowired
    UserInfoMapper userInfoMapper;
    @Autowired
    AddressMapper userAddressMapper;
    @Autowired
    ClothMapper clothMapper;
    @Autowired
    StockMapper stockMapper;
    @Autowired
    SizeMapper sizeMapper;
    @Autowired
    ColorMapper colorMapper;
    @Autowired
    ShoppingCarMapper shoppingCarMapper;
    @Autowired
    OrderInfoMapper orderInfoMapper;
    @Autowired
    OrderDetailMapper orderDetailMapper;
    @Override
    public Result addProductInCar(OrderDeliverDto orderDeliverDto) {
        boolean checkout = checkoutUserInfo(orderDeliverDto.getUserId());
        if (checkout){
            StockView po = new StockView();
            po.setColor(orderDeliverDto.getColor());
            po.setClothId(orderDeliverDto.getClothId());
            po.setSpec(orderDeliverDto.getSpec());
            po.setSpecId(orderDeliverDto.getSpecId());
            po.setColorId(orderDeliverDto.getColorId());
            StockView stockView =stockMapper.getStockInfo(po);
            Integer number=orderDeliverDto.getNumber();
            if(stockView.getStock()<number){
                return Result.ok("库存不足！");
            }
            Integer colorId = stockView.getColorId();
            Integer specId = stockView.getSpecId();
            //购物车里没有的情况
            ShoppingCar shoppingCarPo = new ShoppingCar();
            shoppingCarPo.setUserId(orderDeliverDto.getUserId());
            shoppingCarPo.setColorId(colorId);
            shoppingCarPo.setClothId(orderDeliverDto.getClothId());
            shoppingCarPo.setSpecId(specId);
            ShoppingCar shoppingCar = shoppingCarMapper.queryCarInfo(shoppingCarPo);
            if (shoppingCar==null){
                Integer count=0;
                //插入购物车
                // 创建 SimpleDateFormat 对象来格式化日期
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                Date currentDate = new Date();
                String formattedDate = sdf.format(currentDate);
                try {
                    Date parsedDate = sdf.parse(formattedDate);
                    shoppingCarPo.setCreateTime(parsedDate);
                    shoppingCarPo.setNumber(number);
                    shoppingCarPo.setIsFlag(ShoppingCarStaticNum.FLAG_FALSE);
                    count=shoppingCarMapper.insert(shoppingCarPo);
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
                if (count<1){
                    return Result.fail("插入失败！");
                }
                return Result.ok("插入成功");
            }
            //购物车里有
            shoppingCar.setNumber(shoppingCar.getNumber()+number);
            shoppingCarMapper.updateById(shoppingCar);
            return Result.ok("已存在该商品，加入库存成成功");
        }
        return Result.fail("用户不存在");
    }

    /**
     * @param userId

     * }
     */
    @Override
    public Map<String, List<CarVo>> queryCarList(Integer userId) {
        List<ShoppingCar> shoppingCars=shoppingCarMapper.query(userId);
        Map<String, List<CarVo>> carsMap = new HashMap<>();
        if (shoppingCars.size()>0) {
            for (ShoppingCar shoppingCar : shoppingCars) {
                ClothDto clothDto = new ClothDto();
                clothDto.setClothId(shoppingCar.getClothId());
                clothDto.setSpecId(shoppingCar.getSpecId());
                clothDto.setColorId(shoppingCar.getColorId());
                StockView stockView = stockMapper.query(clothDto);
                Cloth displayClothVo = clothMapper.getProductInfo(shoppingCar.getClothId());
                CarVo carVo = new CarVo();
                Integer clothId = shoppingCar.getClothId();
                carVo.setId(shoppingCar.getId());
                carVo.setColor(stockView.getColor());
                carVo.setColorId(stockView.getColorId());
                carVo.setSpecId(stockView.getSpecId());
                carVo.setPrice(displayClothVo.getPrice());
                carVo.setSpec(stockView.getSpec());
                carVo.setIsFlag(shoppingCar.getIsFlag());
                carVo.setImgUrl(stockView.getImgUrl());
                carVo.setClothName(displayClothVo.getClothName());
                carVo.setClothId(displayClothVo.getId());
                carVo.setStockNumber(stockView.getStock());
                carVo.setNumber(shoppingCar.getNumber());
                carVo.setUserId(userId);
                Date createTime = shoppingCar.getCreateTime();
                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
                String createTimeString = formatter.format(createTime);
                carVo.setCreatTime(createTimeString);
                carsMap.computeIfAbsent(createTimeString,k-> new ArrayList<>()).add(carVo);
            }
        }
        return carsMap;
    }

    /**
     * @return
     */
    @Override
    public Result updateCarNum(Integer id, Integer number) {
        // 将日期加上一天
        ShoppingCar shoppingCarPo = new ShoppingCar();
        shoppingCarPo.setId(id);
        shoppingCarPo.setNumber(number);

        ShoppingCar shoppingCar=shoppingCarMapper.queryCarInfo(shoppingCarPo);
        StockView po = new StockView();
        po.setColorId(shoppingCar.getColorId());
        po.setClothId(shoppingCar.getClothId());
        po.setSpecId(shoppingCar.getSpecId());
        StockView stockInfo = stockMapper.getStockInfo(po);
        if (stockInfo.getStock()<number){
            return Result.fail("库存不足！");
        }
        shoppingCar.setNumber(number);
        Integer i=shoppingCarMapper.updateById(shoppingCarPo);
        if (i>0){
            return Result.ok("修改成功");
        }
        return Result.fail("修改失败");
    }

    /**
     */
    @Override
    public Result deleteCarInfoOne(Integer id) {
        ShoppingCar shoppingCarPo = new ShoppingCar();
        shoppingCarPo.setId(id);
        Integer i=shoppingCarMapper.deleteById(shoppingCarPo);
        if (i>0){
            return Result.ok("删除成功");
        }
        return Result.fail("删除失败");
    }

    /**
     * @param userId
     * @return
     */
    @Override
    public Result deleteCarInfo(Integer userId) {
        boolean flag=false;
        List<ShoppingCar> shoppingCars=shoppingCarMapper.query(userId);
        int size = shoppingCars.size();
        if (size>0){
            List<Integer> ids = shoppingCars.stream().map(ShoppingCar::getId).collect(Collectors.toList());
            HashMap<String, Object> paramMap = new HashMap<>();
            paramMap.put("ids",ids);
            paramMap.put("userId",userId);
            Integer i = shoppingCarMapper.deleteByIds(paramMap);
            if (size==i){
                flag=true;
            }
        }
        return Result.ok(flag);
    }

    /**
     * @param carVoList
     * @return
     */
    @Override
    public Result checkoutCar(List<CarVo> carVoList,UserAddress userAddress,String remark,int orderType) {
        OrderInfo orderInfo = new OrderInfo();
        OrderInfo orderInfoPo = new OrderInfo();
        List<OrderDetail> orderDetailPos = new ArrayList<>();
        Integer userId = null;
        UserInfo userInfo=new UserInfo();
        //生成订单编号/订单id
        Date nowDate = GetNowDateUtil.getNowDate();
        SimpleDateFormat outputFormat = new SimpleDateFormat("yyyyMMdd");
        String result = outputFormat.format(nowDate);
        String orderNo="SALTS"+result+getRandom(6)+orderType;
        int hashCode = orderNo.hashCode();
        int orderId = Math.abs(hashCode);
        Timestamp currentTime = new Timestamp(System.currentTimeMillis());
        //查询库存，生成订单明细
        for (int i = 0; i < carVoList.size(); i++) {
            OrderDetail orderDetailPo = new OrderDetail();
            CarVo carVo = carVoList.get(i);
            if (i==0){
                userId=carVo.getUserId();
            //查询用户信息
            userInfo = userInfoMapper.queryUserInfo(carVo.getUserId());
            }
            //查询库存信息
            StockView stockView = new StockView();
            stockView.setClothId(carVo.getClothId());
            stockView.setSpecId(carVo.getSpecId());
            stockView.setColorId(carVo.getColorId());
            StockView stockInfo = stockMapper.getStockInfo(stockView);
            if (stockInfo==null){
                return Result.fail("未查到对象");
            }
            if (stockInfo.getStock()<carVo.getNumber()){
                return Result.ok(carVo.getClothName()+"库存不足");
            }
            orderDetailPo.setOrderId(orderId);
            orderDetailPo.setOrderNo(orderNo);
            orderDetailPo.setOrderDetailId(i);
            orderDetailPo.setClothId(carVo.getClothId());
            orderDetailPo.setSkuName(carVo.getClothName());
            orderDetailPo.setSkuSpec(carVo.getSpec());
            orderDetailPo.setSkuColor(carVo.getColor());
            orderDetailPo.setSkuPrice(carVo.getPrice());
            orderDetailPo.setPurchaseNum(carVo.getNumber());
            orderDetailPo.setDiscountAmount(carVo.getDiscountAmount()!=null?carVo.getDiscountAmount(): BigDecimal.valueOf(0));
            orderDetailPo.setPlatformAmount(carVo.getPlatformAmount()!=null?carVo.getPlatformAmount(): BigDecimal.valueOf(0));
            orderDetailPo.setShopAmount(carVo.getShopAmount()!=null?carVo.getShopAmount(): BigDecimal.valueOf(0));
            BigDecimal price = carVo.getPrice();
            orderDetailPo.setPayAmount(price.multiply(BigDecimal.valueOf(carVo.getNumber())));
            orderDetailPo.setSkuPurchasePrice(carVo.getPrice());
            orderDetailPo.setSkuPayPrice(orderDetailPo.getSkuPurchasePrice()
                    .subtract(orderDetailPo.getDiscountAmount())
                    .subtract(orderDetailPo.getPlatformAmount())
                    .subtract(orderDetailPo.getShopAmount()));
            if (orderType==0){
                orderDetailPo.setPromoType(1);
            }if (orderType==1){
                orderDetailPo.setPromoType(2);
            }
            orderDetailPo.setOrderDetailState(1);
            orderDetailPos.add(orderDetailPo);
        }
        //计算总金额
        BigDecimal totalAmount = carVoList.stream().map(carVo -> carVo.getPrice().multiply(BigDecimal.valueOf(carVo.getNumber())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        //生成订单表头
        orderInfoPo.setUserId(userId);
        orderInfoPo.setPayType("1");
        orderInfoPo.setPayChannel(null);
        orderInfoPo.setOrderId(orderId);
        orderInfoPo.setOrderNo(orderNo);
        orderInfoPo.setOrderCreateTime(currentTime);
        orderInfoPo.setTotalAmount(totalAmount);
        orderInfoPo.setDiscountAmount(totalAmount);
        orderInfoPo.setShopAmount(totalAmount);
        orderInfoPo.setPlatformAmount(totalAmount);
        orderInfoPo.setFreight(Freight.FREIGHT);
        orderInfoPo.setPayAmount(BigDecimal.valueOf(0));
        orderInfoPo.setPickName(userInfo.getUserName());
        orderInfoPo.setPickAddress(userAddress.getAddress());
        orderInfoPo.setPickPhone(userInfo.getMobile());
        orderInfoPo.setRemark(remark);
        orderInfoPo.setOrderState(0);
        orderInfoPo.setMerchantName(Freight.MERCHANT_NAME);
        orderInfoPo.setProvinceName(userAddress.getProvinceName());
        orderInfoPo.setCityName(userAddress.getCityName());
        orderInfoPo.setAreaName(userAddress.getAreaName());
        orderInfoPo.setOrderType(orderType);
        //插入订单表头 中途有失败就撤销操作 事务
        Result insertInfo = insertOrderInfo(orderInfoPo, orderDetailPos);
        if (insertInfo.getSuccess()){
            //删除购物车内数据
            HashMap<String, Object> paramMap = new HashMap<>();
            List<Integer> collect = carVoList.stream().map(CarVo::getId).collect(Collectors.toList());
            paramMap.put("ids",collect);
            paramMap.put("userId",userId);
            Integer i = shoppingCarMapper.deleteByIds(paramMap);
            if (i>0){
                return Result.ok("下单成功");
            }
            return Result.fail("下单成功，但购物车对象未清空！之后请手动删除");
        }
        return Result.fail("生成订单失败，请稍后重试！");
    }

    /**
     * @param carVo 整个carVo对象
     * @return
     */
    @Override
    public Result updateIsFlag(CarVo carVo) {
        StockView stockView = new StockView();
        stockView.setClothId(carVo.getClothId());
        stockView.setSpec(carVo.getSpec());
        stockView.setColor(carVo.getColor());
        StockView stockInfo = stockMapper.getStockInfo(stockView);
        ShoppingCar shoppingCarPo = new ShoppingCar();
        shoppingCarPo.setUserId(carVo.getUserId());
        shoppingCarPo.setColorId(stockInfo.getColorId());
        shoppingCarPo.setClothId(carVo.getClothId());
        shoppingCarPo.setSpecId(stockInfo.getSpecId());
        ShoppingCar shoppingCar = shoppingCarMapper.queryCarInfo(shoppingCarPo);
        shoppingCar.setIsFlag(carVo.getIsFlag());
        return Result.ok(shoppingCarMapper.updateIsFlagById(shoppingCar)>0);
    }

    private boolean checkoutUserInfo(Integer userId){
        boolean flag=false;
        flag=userInfoMapper.selectByPrimaryKey(userId)>0;
        return flag;
    }
    public boolean createOrder(OrderInfo orderInfo) {
        return orderInfoMapper.insertOrderInfo(orderInfo)>0;
    }
    public boolean createOrderDetail(List<OrderDetail> orderDetails) {
        return orderDetailMapper.insertAllOrderDetail(orderDetails)==orderDetails.size();
    }

    Integer getRandom(int number){
        if (number <= 0) {
            throw new IllegalArgumentException("位数必须大于0");
        }
        int min = (int) Math.pow(10, number - 1); // 计算最小值
        int max = (int) Math.pow(10, number) - 1; // 计算最大值
        Random random = new Random();
        return random.nextInt(max - min + 1) + min; // 生成范围在min到max之间的随机数
    }
    @Transactional
    Result insertOrderInfo(OrderInfo orderInfoPo,List<OrderDetail> orderDetailPos){
        boolean orderFlag = createOrder(orderInfoPo);
        if (!orderFlag){
            return Result.fail("插入订单失败");
        }
        //插入订单明细 中途有失败就撤销操作 事务
        boolean orderDetail = createOrderDetail(orderDetailPos);
        if (!orderDetail){
            return Result.fail("插入订单明细失败");
        }
        return Result.ok();
    }
}
